home *** CD-ROM | disk | FTP | other *** search
- XDEF _compress_slow
-
- ;On entry:
- ; a0 = InBuf
- ; a1 = OutBuf
- ; a2 = HashTab
- ; d0 = InLen
-
- CODE
-
- COMPRESSREGS reg a3-a6/d1-d7
- _compress_slow:
- movem.l COMPRESSREGS,-(sp)
- move.l a0,d1
- add.l d0,d1 ; d1=src+src_len
-
- moveq.l #$FFFFFFFC,d2
- and.l d0,d2
- add.l a1,d2
- move.l d2,a4 ; a4=(dst+src_len) & ~3
-
- movem.l a1/a4,-(sp) ; save dst and dst_end for later use
-
- moveq.l #1,d0
- swap d0
- move.l a2,a6
- add.l d0,a6
- ;;; lea $10000(a2),a6 ; a6=hh a6-$10000 == hash
-
- moveq.l #0,d0
- move.w #$9FF,d2
- hfill: move.l d0,(a2)+ ; fill hash with $00000000
- move.l d0,(a2)+ ; hash is $A00*8 = $5000 longs big
- move.l d0,(a2)+
- move.l d0,(a2)+
- move.l d0,(a2)+
- move.l d0,(a2)+
- move.l d0,(a2)+
- move.l d0,(a2)+
- dbra d2,hfill
-
- move.l a0,a2 ; d0 = 4*hash_fkt(s,s+1,s+2)
- moveq.l #-1,d0
- move.b (a2)+,d0
- asl.w #3,d0
- add.b (a2)+,d0
- asl.w #3,d0
- add.b (a2),d0
- asl.w #2,d0
-
- move.l a0,0(a6,d0.l) ;hash[hash_val]=s
-
- move.l #$00000FFF,d4
-
- bra.s entry_point
-
- ;REGISTER MAP
- ;============
-
- ; a0 source
- ; a1 destination byte stream (post increment)
- ; a2 Temporary
- ; a3 work pointer into LZ77-window
- ; a4 destination word stream (pre decrement)
- ; a5 Temporary
- ; a6 hashtable
- ; a7 Stack pointer. Don't touch!
-
- ; d0 Temporary
- ; d1 End of input
- ; d2 src - 4095
- ; d3 match_offset , match_len
- ; d4 Constant 4095
- ; d5 place to put control word in output
- ; d6 Counter of Controlbits to insert into the control word.
- ; d7 Buffers the current control word.
-
- ;;;---------------------------------------------------------------------------
-
- newctl: move.l d5,a2
- move.w d7,(a2) ; write ctrl_word to it's place
- entry_point:
- subq.l #2,a4
- move.l a4,d5 ; get place to put next ctrl_word
-
- moveq.l #15,d6 ; reinitialize ctrl_bit_counter
- moveq.l #-1,d7 ; fill ctrl_word with $FFFF
-
- oloop: move.l a0,a3 ; wrk=s
- move.l a0,d2
- sub.l d4,d2 ; limit = src - 4095
- moveq.l #2,d3 ; match_ofs,match_len = 0,2
-
- iloop: move.l a3,d0 ; d0=$00000FFF
- and.l d4,d0 ; d0=wrk & $00000FFF
- asl.w #2,d0
- move.l 0(a6,d0.l),a3 ; p=hh[p & $00000FFF]
-
- cmp.l d2,a3 ; has src reached the limit
- bcs.s finished_chain ; is a3 < d2
-
- move.l a0,a2
- move.l a3,a5
-
- MATCH MACRO
- cmp.b (a2)+,(a5)+
- bne.s \1
- ENDM
- MATCH iloop ; 0
- MATCH iloop ; 1
- MATCH iloop ; 2
- MATCH mism ; 3
- MATCH mism ; 4
- MATCH mism ; 5
- MATCH mism ; 6
- MATCH mism ; 7
- MATCH mism ; 8
- MATCH mism ; 9
- MATCH mism ;10
- MATCH mism ;11
- MATCH mism ;12
- MATCH mism ;13
- MATCH mism ;14
- MATCH mism ;15
- MATCH mism ;16
- MATCH mism ;17
- addq.l #1,a5 ;18
- mism: move.l a5,d0
- sub.l a3,d0
- subq.w #1,d0 ; d0=match_len
-
- cmp.w d0,d3
- bcc.s iloop ; new match is not longer than old one
-
- move.l a0,d3
- sub.l a3,d3 ; d4 = src - wrk = match_ofs
- swap d3
- move.w d0,d3 ; match_ofs,match_len is updated.
-
- cmp.b #18,d3
- bcs.s iloop ; match_len < 18
-
- finished_chain:
- cmp.b #3,d3
- bcs.s do_literal
-
- moveq.l #18,d0
- sub.b d3,d0 ; d0=18-match_len
-
- swap d3
- asl.w #4,d3
- or.b d0,d3 ; d3 = OOOOOOOO OOOOLLLL
-
- move.w d3,-(a4) ; write copyinfo
-
- swap d3 ; d3.w = match_len
- subq.w #1,d3 ; d3 = match_len - 1
-
- rol.w #1,d7 ; inject a 1 into control word
- bra.s incsrc
-
- do_literal:
- moveq.l #0,d3 ; d4 = [pseudo]match_len - 1
- move.b (a0),(a1)+ ; write literal
- add.w d7,d7 ; inject 0 into ctrl_word
-
- incsrc: addq.l #1,a0 ; increment src
-
- move.l a0,a2
- moveq.l #-1,d0
- move.b (a2)+,d0
- lsl.w #3,d0
- add.b (a2)+,d0
- lsl.w #3,d0
- add.b (a2)+,d0
- asl.w #2,d0 ; d0 = hash_fkt(src[0],src[1],src[2])
-
- move.l 0(a6,d0.l),a2 ; a2 = hash[hash_val]
- move.l a0,0(a6,d0.l) ; hash[hash_val] = src
-
- move.l a0,d0
- and.l d4,d0
- asl.w #2,d0
- move.l a2,0(a6,d0.l) ; hh[src&$FFF] = src - [old]hash[hash_val]
- dbra d3,incsrc
-
- cmp.l a0,d1 ; Has src reached src_end?
- bcs.s end_compress_loop
- dbra d6,oloop
- bra newctl
-
- ;;; The rest is copied from compress_fast !!!! FIXME !!!!
- ;;; Only the registers are renamed :-(
-
- ;;;The main loop ends here.
- ;;;---------------------------------------------------------------------------
- ;FINALIZATION
- ;============
-
- FillControl: ;Fill the rest of the control word with 0
- add.w d7,d7 ;0 means literal items.
- end_compress_loop:
- dbra d6,FillControl
-
- move.l d5,a2
- move.w d7,(a2) ;Write it to its output position
-
- movem.l (sp)+,d6/d7 ; Pop dst and dst_end
-
- ;Copy the literals after the word stream pointed to by a1.
- move.l a4,d0 ;d0:=Number of Bytes to increase a1
- sub.l a1,d0 ;till a1 and a4 are equally aligned.
- bcc.s did_compress
-
- ;byte- and wordstream together do exceede the size of the output buffer.
- moveq #0,d0 ; return 0 to indicate overrun
- bra.s finish
-
- did_compress:
- moveq #3,d1
- and.w d0,d1
-
- moveq.l #0,d0 ;pad a1 up to make a1 and a4 equally aligned.
- bra.s EFLoop
- FLoop: move.b d0,(a1)+
- EFLoop: dbra d1,FLoop
-
- sub.l a4,d7 ;d7:=size of wordstream
-
- lsr.l #2,d7
- bcc.s ECLoop ;make sure we do the move.l longword aligned.
- move.w (a4)+,(a1)+
- NoWord: bra.s ECLoop
- CLoopH: swap d7
- CLoop: move.l (a4)+,(a1)+
- ECLoop: dbra d7,CLoop
- swap d7
- dbra d7,CLoopH
-
- move.l a1,d0
- sub.l d6,d0 ;d0:=Final output length
- finish: movem.l (sp)+,COMPRESSREGS
- rts
-
- ;;;---------------------------------------------------------------------------
-
- END
-
-